const express = require('express')
const mysql = require('mysql')
const nodemailer = require('nodemailer');
const db = mysql.createPool({
    host: '127.0.0.1',
    user: 'root',
    password: '123456',
    database: 'paper'
})
const uid = require('node-uuid')
const fs = require('fs')
const path = require('path')
const multer = require("multer");
let Router = express.Router()

Router.all('*', function (req, res, next) {
    res.header('Access-Control-Allow-Origin', 'http://127.0.0.1:8080');
    res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization');
    res.set('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Allow-Methods', '*');
    next();
})

Router.use(express.json())
Router.use(express.urlencoded({ extended: false }))

//用来生成token加密字符串
const jwt = require("jsonwebtoken")
//用来解析客户端返回的token信息
const expressJWT = require("express-jwt")

//此外还需要另外定义一个密钥 本质上就是一个字符串 随便写什么都可以 越复杂越好
//防止密钥在网络传输中被破解
const secretKey = "paper"

Router.use(
    expressJWT.expressjwt({ secret: secretKey, algorithms: ["HS256"] }).unless({
        path: [/^\/api\//],
    })
);
//token全局变量
let token;

let transporter = nodemailer.createTransport({
    //配置服务器的发送邮箱和登录信息
    service: 'qq',//163、qq等
    port: 465,//默认qq邮箱的端口号
    auth: {
        user: '',//邮箱
        pass: ''//邮箱密码或授权码
    }
});
//全局变量,保存用户的验证码,用来校验。
let keyCode;
//生成验证码
function createKey() {
    let key = '';
    //生成一个随机六位数验证码
    for (let i = 1; i <= 6; i++) {
        key = key + String(Math.floor(Math.random() * 10))
    }
    return key
}
//用户注册发送验证码到邮箱
Router.get('/api/sendMail', (req, res) => {
    // console.log(req.query.email)
    keyCode = createKey()
    //配置接收者的相关配置
    let option = {
        from: 'wallPaper作者<2516513576@qq.com>',//'"邮件显示名" <xxx@qq.com>',
        to: req.query.email,//接受者 
        subject: 'wallPaper',//主题名
        html: `<h2>您正在注册paper用户
                    验证码为${keyCode}</h2>
                    请不要将验证码泄露给别人
                    如果不是您本人操作,请不要将验证码泄露
                `,//内容,
    }
    transporter.sendMail(option, function (err, info) {
        if (err) {
            console.log(err)
            res.send({
                msg: '发送验证码失败,请检查邮箱'
            })
        } else {
            res.send({
                status: 200,
                msg: '发送成功,请注意邮箱信息'
            })
        }
    })
})

//当用户点击注册的时候的中间件,注册之前先检查用户名是否被注册,同时验证验证码是否正确
function checkNameOrkeyCode(req, res, next) {
    let sql = `select userName from user`
    let isRegister = false
    //这里特别注意数据库操作是异步的操作,如果把判断是否注册放在查询外面,会出现数据库查询结果没出来,下面的语句已经执行了
    db.query(sql, req.body.userName, (err, result) => {
        result.forEach(item => {
            if (item.userName == req.body.userName) {
                isRegister = true
            }
        });

        if (keyCode != req.body.keyCode) {
            res.send({ status: 428, msg: '验证码错误' })
        } else {
            isRegister ? res.send({ status: 412, msg: "此用户名已被注册" }) : next()
        }
    });

}
//注册接口
Router.post('/api/register', checkNameOrkeyCode, (req, res) => {
    let user = req.body
    let sql = `insert into user (id,userName,passWord,email) value(?,?,?,?)`
    //根据uuid生成唯一id
    db.query(sql, [uid.v1(), user.userName, user.passWord, user.email], (err) => {
        if (err) {
            res.send({
                status: 500,
                msg: "错误信息"
            })
        } else {
            res.send({
                status: 200,
                msg: "注册成功"
            })
            keyCode = ''
        }

    })
})
//登录接口
Router.post('/api/login', (req, res) => {
    let user = req.body
    let sql = `select * from user where userName = ?`
    db.query(sql, user.userName, (err, result) => {
        if (result.length == 0) {
            res.send({
                status: 400,
                msg: '账号或者密码错误'
            })
        } else {
            if (result[0].userName == user.userName && result[0].passWord == user.passWord) {
                console.log(result[0])
                //返回给前端的userVo信息对象
                let userVo = {
                    id: result[0].id,
                    userName: result[0].userName,
                    email: result[0].email,
                    userImg: result[0].userImg,
                    bgImg: result[0].bgImg
                }
                //生成token
                token = jwt.sign(userVo, secretKey, { expiresIn: '24h' })
                res.send({
                    status: 200,
                    msg: '登录成功',
                    userinfo: userVo,
                    token: token
                })
            } else {
                res.send({
                    status: 400,
                    msg: '账号或者密码错误'
                })
            }
        }
    });
})


//根据token获取信息,保持登录状态
Router.get('/user/getinfo', (req, res) => {
    res.send({
        status: 200,
        userinfo: req.auth
    })
})

//token过期重新派发给客户端token
// Router.get('/api/resetToken', (req, res) => {
//     console.log(req)
//     res.send({
//         msg: 'token'
//     })
// })

//中间件函数,用来判断文件夹是否存在,无论是更新头像,还是上传壁纸等等...
function isFileExit(req, res, next) {
    userRootpath = path.join(__dirname, '/public', `/${req.auth.id}`)
    userUploadPath = path.join(__dirname, '/public', `${req.auth.id}`, '/uploads')
    //判断文件夹是否存在,不存在则创建
    //先创建一级目录
    function createFile(path) {
        return new Promise((res, rej) => {
            fs.access(path, (err) => {
                if (err) {
                    fs.mkdir(path, (err) => {
                        res()
                    })
                } else {
                    res()
                }
            })
        })
    }

    createFile(userRootpath).then((value) => {
        Promise.all([createFile(userUploadPath)]).then((allValue) => {
            next()
        })
    })

}

//设置磁盘存贮
let storage = multer.diskStorage({
    destination: function (req, file, cb) {
        let userFilePath = '';
        let reqPath = req._parsedUrl.pathname
        if (reqPath == '/user/updataImg' || reqPath == '/user/updataBgImg') {
            userFilePath = path.join(__dirname, '/public', `${req.auth.id}`)

            cb(null, userFilePath);//设置文件存储路径
        } else if (reqPath == '/user/uploadImg') {
            userFilePath = path.join(__dirname, '/public', `${req.auth.id}`, '/uploads')

            cb(null, userFilePath);//设置文件存储路径
        }
    },

    filename: function (req, file, cb) { // 在这里设定文件名
        // cb(null, file.originalname); // file.originalname是将文件名设置为上传时的文件名，file中携带的
        cb(null, Date.now() + '-' + file.originalname) // 加上Date.now()可以避免命名重复
    }
})
let upload = multer({ storage: storage })

//用户更新头像操作
Router.post('/user/updataImg', isFileExit, upload.single('file'), (req, res) => {
    let sql = 'update user set userImg = ? where id =?'
    db.query(sql, [req.file.filename, req.auth.id], (err, result) => {
        if (err) {
            res.send({
                status: 500,
                msg: '抱歉,服务器出现了点问题'
            })
        } else {
            let sql = `select * from user where id = ?`
            db.query(sql, req.auth.id, (err, result) => {
                let userVo = {
                    id: result[0].id,
                    userName: result[0].userName,
                    email: result[0].email,
                    userImg: result[0].userImg,
                    bgImg: result[0].bgImg
                }
                // token = jwt.sign(userVo, secretKey)
                res.send({
                    status: 200,
                    userinfo: userVo,
                    // token: token
                })
            })

        }
    })
})

//更新用户背景图片操作
Router.post('/user/updataBgImg', isFileExit, upload.single('file'), (req, res) => {
    let sql = 'update user set bgImg = ? where id =?'
    db.query(sql, [req.file.filename, req.auth.id], (err, result) => {
        if (err) {
            res.send({
                status: 500,
                msg: '抱歉,服务器出现了点问题'
            })
        } else {
            let sql = `select * from user where id = ?`
            db.query(sql, req.auth.id, (err, result) => {
                let userVo = {
                    id: result[0].id,
                    userName: result[0].userName,
                    email: result[0].email,
                    userImg: result[0].userImg,
                    bgImg: result[0].bgImg
                }
                // token = jwt.sign(userVo, secretKey)
                res.send({
                    status: 200,
                    userinfo: userVo,
                    // token: token
                })
            })
        }
    })
})

//用户上传壁纸
Router.post('/user/uploadImg', isFileExit, upload.single('file'), (req, res) => {
    let sql = `insert into uploadimg (userId,imgId,imgPath,tags,date) value(?,?,?,?,?)`

    let date = new Date()
    let time = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
    //将tags对象转换为数组，再转换为一定格式的字符串存进数据库
    let str = JSON.parse(req.query.tags)
    let tags = [];
    str.forEach(item => {
        tags.push(item.tagName)
    })
    db.query(sql, [req.auth.id, uid.v1(), req.file.filename, tags.toString(), time], (err) => {
        if (err) {
            console.log(err)
            res.send({
                status: 500,
                msg: "抱歉,服务器出现了点问题"
            })
        } else {
            res.send({
                status: 200,
                msg: '上传成功'
            })
        }
    })
})

//用户删除壁纸中间件，将文件夹对应的壁纸删除掉
function deleteUpload(req, res, next) {
    let filePath = path.join(__dirname, '/public', `/${req.query.userId}`, '/uploads', `/${req.query.imgPath}`)
    fs.unlink(filePath, (err) => {
        if (err) {
            res.send({
                status: 500,
                mgs: '删除失败'
            })
        } else {
            next()
        }
    })
}

//用户删除壁纸
Router.get('/user/deleteUpload', deleteUpload, (req, res) => {
    let sql = `delete from uploadimg where imgId = ?`
    db.query(sql, req.query.imgId, (err) => {
        if (err == null) {
            //返回新的壁纸列表
            let sqlQuery = `select * from uploadimg where userId = ?`
            db.query(sqlQuery, req.query.userId, (err, result) => {
                res.send({
                    status: 200,
                    uploadList: result,
                })
            })
        }
    })
})

//用户收藏壁纸
Router.post('/user/collected', (req, res) => {
    let userId = req.body.userId
    let imgDetail = req.body.imgDetail
    let sql = `insert into collections (userId,imgId,tags,imgPath,uploadId) value(?,?,?,?,?)`
    db.query(sql, [userId, imgDetail.imgId, imgDetail.tags.toString(), imgDetail.imgPath, imgDetail.userId], (err, result) => {
        res.send({
            status: 200,
            msg: '收藏成功'
        })
    })
})

//用户删除自己收藏的壁纸
Router.get('/user/deleteCollected', (req, res) => {
    let imgId = req.query.imgId
    let sql = `delete from collections where imgId = ?`
    db.query(sql, imgId, (err, result) => {
        if (err == null) {
            let sqlquery = `select imgId,tags,imgPath,uploadId from collections where userId = ?`
            db.query(sqlquery, req.auth.id, (err2, result2) => {
                res.send({
                    status: 200,
                    collections: result2
                })
            })
        }
    })
})


//发送修改密码验证码请求
Router.post('/user/sendKey', (req, res) => {
    keyCode = createKey()
    //配置接收者的相关配置
    let option = {
        from: 'wallPaper作者<2516513576@qq.com>',//'"邮件显示名" <xxx@qq.com>',
        to: req.auth.email,//接受者 
        subject: 'wallPaper',//邮件主题
        html: `<h2>您正在修改密码
                    验证码为${keyCode}</h2>
                    请不要将验证码泄露给别人
                    如果不是您本人操作,请不要将验证码泄露
                `,//内容,
    }
    transporter.sendMail(option, function (err, info) {
        if (err) {
            console.log(err)
            res.send({
                msg: '发送验证码失败'
            })
        } else {
            res.send({
                msg: '发送成功,请注意邮箱信息'
            })
        }
    })
})

//校验验证码,用户修改密码
Router.post('/user/updataPassword', (req, res) => {
    if (req.body.code == keyCode) {
        let sql = `update user set passWord = ? where id =?`
        db.query(sql, [req.body.passWord, req.auth.id], function (err, result) {
            if (err) {
                res.send({
                    msg: '抱歉,服务器出了点错误'
                })
            } else {
                //修改成功之后让验证码失效(重新赋值为空)
                keyCode = ''
                res.send({
                    status: 200,
                    msg: '修改密码成功'
                })
            }
        })
    } else {
        res.send({
            msg: '验证码错误'
        })
    }
})


module.exports = Router